"""
AI报告业务服务层

协调各个组件，处理报告生成的业务逻辑。
提供统一的报告生成接口，支持不同类型的报告生成。
"""

from typing import Dict, Any, Optional
import logging
from datetime import datetime
import tempfile
import os
import asyncio

from ..core.report_generator import ReportResult, BaseReportGenerator
from ..config.report_config import ReportConfig, get_report_config
from client.openai_client import invoke_openai_only_result
from utils.oss_util import upload_file_to_oss
from utils.mongo_util import db

import markdown
import pdfkit

logger = logging.getLogger(__name__)


class FileService:
    """文件处理服务"""
    
    def __init__(self, config: ReportConfig):
        self.config = config
        self.logger = logging.getLogger(self.__class__.__name__)
    
    async def create_and_upload_pdf(self, html_content: str, file_name: str) -> Optional[str]:
        """
        创建PDF并上传到OSS
        
        Args:
            html_content: HTML内容
            file_name: 文件名
            
        Returns:
            str: OSS文件URL，失败时返回None
        """
        try:
            # 创建临时文件
            with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as temp_pdf:
                temp_path = temp_pdf.name
            
            try:
                # 配置pdfkit
                config = self.config.get_pdf_kit_config()
                options = self.config.pdf_config.options
                
                # 生成PDF
                pdfkit.from_string(
                    html_content,
                    temp_path,
                    configuration=config,
                    options=options
                )
                
                # 上传到OSS
                upload_url = upload_file_to_oss(temp_path, file_name, 'application/pdf')
                
                if upload_url:
                    self.logger.info(f"PDF文件已上传至OSS: {file_name}")
                    return upload_url
                else:
                    self.logger.error(f"PDF文件上传失败: {file_name}")
                    return None
                    
            finally:
                # 清理临时文件
                try:
                    os.unlink(temp_path)
                except OSError:
                    pass
                    
        except Exception as e:
            self.logger.error(f"PDF生成失败: {str(e)}", exc_info=True)
            return None
    
    def generate_file_name(self, report_type: str, context: Dict[str, Any]) -> str:
        """
        生成文件名
        
        Args:
            report_type: 报告类型
            context: 上下文信息
            
        Returns:
            str: 生成的文件名
        """
        pattern = self.config.get_file_name_pattern(report_type)
        
        # 获取当前时间戳
        timestamp = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3]
        
        # 准备替换变量
        variables = {
            'timestamp': timestamp,
            'member_name': context.get('member_name', '未知'),
            'depart_name': context.get('depart_name', '未知'),
            'project_name': context.get('project_name', '未知')
        }
        
        # 替换占位符
        file_name = pattern.format(**variables)
        
        return file_name


class AIService:
    """AI分析服务"""
    
    def __init__(self, config: ReportConfig):
        self.config = config
        self.logger = logging.getLogger(self.__class__.__name__)
    
    async def analyze_data(self, prompt: str, max_retries: int = None) -> str:
        """
        使用AI分析数据
        
        Args:
            prompt: AI提示词
            max_retries: 最大重试次数
            
        Returns:
            str: AI分析结果
        """
        if max_retries is None:
            max_retries = self.config.ai_config.max_retries
        
        for attempt in range(max_retries):
            try:
                self.logger.info(f"调用AI分析，第{attempt + 1}次尝试")
                
                # 调用AI服务
                result = await invoke_openai_only_result(prompt)
                
                # 清理AI返回的内容
                cleaned_result = self._clean_ai_result(result)
                
                self.logger.info("AI分析完成")
                return cleaned_result
                
            except Exception as e:
                self.logger.warning(f"AI分析失败，第{attempt + 1}次尝试: {str(e)}")
                
                if attempt == max_retries - 1:
                    raise Exception(f"AI分析失败，已重试{max_retries}次: {str(e)}")
                
                # 等待一段时间后重试
                await asyncio.sleep(2 ** attempt)
    
    def _clean_ai_result(self, result: str) -> str:
        """
        清理AI返回的结果
        
        Args:
            result: AI原始结果
            
        Returns:
            str: 清理后的结果
        """
        # 移除代码块标记
        result = result.replace('```html', '').replace('```', '')
        
        # 移除多余的空白字符
        result = result.strip()
        
        return result


class ReportService:
    """
    报告生成业务服务
    
    协调各个组件，提供统一的报告生成接口。
    """
    
    def __init__(self, config: ReportConfig = None):
        """
        初始化报告服务
        
        Args:
            config: 报告配置，如果为None则使用默认配置
        """
        self.config = config or get_report_config()
        self.file_service = FileService(self.config)
        self.ai_service = AIService(self.config)
        self.logger = logging.getLogger(self.__class__.__name__)
        
        # 报告生成器注册表
        self._generators: Dict[str, BaseReportGenerator] = {}
    
    def register_generator(self, report_type: str, generator: BaseReportGenerator):
        """
        注册报告生成器
        
        Args:
            report_type: 报告类型
            generator: 报告生成器实例
        """
        self._generators[report_type] = generator
        self.logger.info(f"注册报告生成器: {report_type}")
    
    def get_generator(self, report_type: str) -> BaseReportGenerator:
        """
        获取报告生成器
        
        Args:
            report_type: 报告类型
            
        Returns:
            BaseReportGenerator: 报告生成器实例
            
        Raises:
            ValueError: 如果报告类型不存在
        """
        if report_type not in self._generators:
            raise ValueError(f"未知的报告类型: {report_type}")
        
        return self._generators[report_type]
    
    async def generate_report(self, report_type: str, request_data: Dict[str, Any]) -> ReportResult:
        """
        生成报告
        
        Args:
            report_type: 报告类型（worker, equipment, project等）
            request_data: 请求数据
            
        Returns:
            ReportResult: 报告生成结果
        """
        try:
            self.logger.info(f"开始生成报告: {report_type}")
            
            # 获取报告生成器
            generator = self.get_generator(report_type)
            
            # 生成报告
            result = await generator.generate_report(request_data)
            
            if result.success:
                self.logger.info(f"报告生成成功: {report_type}")
                
                # 记录到数据库
                await self._log_report_generation(report_type, request_data, result)
            else:
                self.logger.error(f"报告生成失败: {report_type}, 错误: {result.error_message}")
            
            return result
            
        except Exception as e:
            error_msg = f"报告生成异常: {str(e)}"
            self.logger.error(error_msg, exc_info=True)
            
            return ReportResult(
                success=False,
                error_message=error_msg
            )
    
    async def _log_report_generation(self, report_type: str, request_data: Dict[str, Any], 
                                   result: ReportResult):
        """
        记录报告生成日志
        
        Args:
            report_type: 报告类型
            request_data: 请求数据
            result: 生成结果
        """
        try:
            log_data = {
                'report_type': report_type,
                'request_data': request_data,
                'result_url': result.url,
                'generated_at': datetime.now(),
                'success': result.success,
                'metadata': result.metadata
            }
            
            # 异步记录到MongoDB
            db.report_log.insert_one(log_data)
            
        except Exception as e:
            self.logger.warning(f"记录报告日志失败: {str(e)}")
    
    async def generate_worker_report(self, request_data: Dict[str, Any]) -> ReportResult:
        """生成工人报告"""
        return await self.generate_report('worker', request_data)
    
    async def generate_equipment_report(self, request_data: Dict[str, Any]) -> ReportResult:
        """生成设备报告"""
        return await self.generate_report('equipment', request_data)
    
    async def generate_project_report(self, request_data: Dict[str, Any]) -> ReportResult:
        """生成项目报告"""
        return await self.generate_report('project', request_data)
    
    def get_supported_report_types(self) -> list:
        """获取支持的报告类型"""
        return list(self._generators.keys())
    
    def get_service_status(self) -> Dict[str, Any]:
        """获取服务状态"""
        return {
            'supported_report_types': self.get_supported_report_types(),
            'config_valid': True,  # 配置已经在初始化时验证
            'ai_service': 'available',
            'file_service': 'available',
            'database_service': 'available'
        }


# 全局服务实例
_global_service: Optional[ReportService] = None


def get_report_service() -> ReportService:
    """获取全局报告服务实例"""
    global _global_service
    if _global_service is None:
        _global_service = ReportService()
    return _global_service


def set_report_service(service: ReportService):
    """设置全局报告服务实例"""
    global _global_service
    _global_service = service